﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using THenu.TinyHourseLib.DesignPattern.Structural_Patterns.Decorator_Pattern.RealWorld;

namespace THenu.TinyHourseLib.DesignPattern.Structural_Patterns.Decorator_Pattern
{
    public class DecoratorPattern : IPatternDemonstrate
    {
        public void StructuralCode()
        {
            // Create ConcreteComponent and two Decorators
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();

            // Link decorators
            d1.SetComponent(c);
            d2.SetComponent(d1);

            d2.Operation();
        }

        public string PatternDescription()
        {
            string description = @"
Definition
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Participants

    The classes and objects participating in this pattern are:

Component   (LibraryItem)
defines the interface for objects that can have responsibilities added to them dynamically.
ConcreteComponent   (Book, Video)
defines an object to which additional responsibilities can be attached.
Decorator   (Decorator)
maintains a reference to a Component object and defines an interface that conforms to Component's interface.
ConcreteDecorator   (Borrowable)
adds responsibilities to the component.";
            return description;
        }

        public void RealWorldExample()
        {
            // Create book
            Book book = new Book("Worley", "Inside ASP.NET", 10);
            book.Display();

            // Create video
            Video video = new Video("Spielberg", "Jaws", 23, 92);
            video.Display();

            // Make video borrowable, then borrow and display
            Console.WriteLine("\nMaking video borrowable:");

            Borrowable borrowvideo = new Borrowable(video);
            borrowvideo.BorrowItem("Customer #1");
            borrowvideo.BorrowItem("Customer #2");

            borrowvideo.Display();
        }
    }
}
